package com.pengshun.modules.api.user.service.impl;

import com.pengshun.modules.api.coal.util.CommonUtil;
import com.pengshun.modules.api.coal.util.SystemPath;
import com.pengshun.modules.api.mapper.PsUserInComRecordMapper;
import com.pengshun.modules.api.mapper.PsUserInfoMapper;
import com.pengshun.modules.api.order.service.dto.IncomeRecordDto;
import com.pengshun.modules.api.order.service.mapstruct.IncomeRecordTodo;
import com.pengshun.modules.api.pay.service.WechatPayService;
import com.pengshun.modules.api.user.para.RunningWaterPara;
import com.pengshun.modules.api.user.para.WithdrawPara;
import com.pengshun.modules.api.user.repository.IncomeRecordRepository;
import com.pengshun.modules.api.user.repository.IncomeRepository;
import com.pengshun.modules.api.user.repository.UserBankRepository;
import com.pengshun.modules.api.user.repository.UserWithdrawRepository;
import com.pengshun.modules.api.user.service.AccountService;
import com.pengshun.modules.api.user.service.dto.QrcodeDto;
import com.pengshun.modules.common.BaseResult;
import com.pengshun.modules.common.BillType;
import com.pengshun.modules.common.OrderCommon;
import com.pengshun.modules.common.PagePara;
import com.pengshun.modules.domain.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.pengshun.modules.api.util.QRCodeUtils.createImage;
import static com.pengshun.modules.api.util.QRCodeUtils.upoos;

/**
 * @author luoligang
 * @create 2021/2/4
 */
@Service
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

    private final IncomeRepository incomeRepository;
    private final WechatPayService wechatPayService;
    private final PsUserInfoMapper psUserInfoMapper;
    private final IncomeRecordRepository incomeRecordRepository;
    private final IncomeRecordTodo incomeRecordTodo;
    private final UserBankRepository userBankRepository;
    private final PsUserInComRecordMapper uirm;
    private final UserWithdrawRepository userWithdrawRepository;
    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public BaseResult getWallet(PagePara para) {
        List<IncomeRecordDto> walletList = psUserInfoMapper.getWalletList(para.getStatus(), para.getPage(), para.getSize(), para.getUserId());
        return new BaseResult(0, walletList);
    }

    @Override
    public BaseResult getRunningWater(RunningWaterPara para) {
        List<IncomeRecordDto> runningWaterList = psUserInfoMapper.getRunningWaterList(para.getDate(), para.getPage(), para.getSize(), para.getUserId());
        return new BaseResult(0, runningWaterList);
    }

    @Override
    public BaseResult getRunningWaterDetil(RunningWaterPara para) {
        IncomeRecordDto dto = incomeRecordTodo.toDto(incomeRecordRepository.findById(para.getIncomeRecordId()).orElseGet(IncomeRecord::new));
        return new BaseResult(0, dto);
    }

    @Override
    public BaseResult getBalance(Long id) {
        Income income = incomeRepository.findByUserId(id);
        return new BaseResult(0, income);
    }

    @Override
    public BaseResult pay(IncomeRecordDto para) throws Exception {
        //充值
        String attach = para.getUserId() + "-" + BillType.BILL_TYPE_FIVE + "-" + para.getUserId();
        return new BaseResult(0, wechatPayService.unifiedorder("余额充值", para.getMoney(), attach, "APP", ""));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult withdraw(IncomeRecordDto para) {
        Income income = incomeRepository.findByUserId(para.getUserId());
        BigDecimal amount = para.getAmount();
        if (amount.compareTo(income.getUsableBlanace()) == 1) {
            return new BaseResult(1, "可用提现金额不足！请刷新后再试");
        }
        UserBank bank = userBankRepository.findById(para.getUserBankId()).orElseGet(UserBank::new);
        //提现记录表加数据
        UserWithdraw withdraw=new UserWithdraw();
        withdraw.setUserId(para.getUserId());
        withdraw.setAmount(amount);
        withdraw.setWithdrawNo("TX"+CommonUtil.getFourRandom());
        withdraw.setUserBankId(para.getUserBankId());
        withdraw.setStatus("1");
        withdraw.setBankName(bank.getBankName());
        withdraw.setBankNumber(bank.getBankCardNo());
        withdraw.setWay("1");
        withdraw.setCreateTime(new Date());
        withdraw= userWithdrawRepository.save(withdraw);
        IncomeRecordDto userincomeRecord = new IncomeRecordDto(para.getUserId(), "TB" + CommonUtil.getFourRandom(), amount,
                OrderCommon.PAYMENT_TYPE_TWO, OrderCommon.BILL_TYPE_SIX,  withdraw.getUserWithdrawId(), OrderCommon.PAY_WAY_FOUR,
                "余额提现", 1, new Date(), 1, bank.getBankName(), bank.getBankSmallIcon(),null);
        incomeRecordRepository.save(incomeRecordTodo.toEntity(userincomeRecord));
        //更新用户余额
        BigDecimal userNowBlanace = income.getUsableBlanace().subtract(amount);
        BigDecimal userNowAccountBlanace = income.getAccountBlanace().subtract(amount);
        uirm.updateBlanace(income.getUsableBlanace(), userNowBlanace,para.getUserId(), income.getAccountBlanace(), userNowAccountBlanace);

        return new BaseResult(0,"提现成功");
        //todo  提现失败 改提现记录状态  改账单记录状态
    }

    @Override
    public BaseResult bill(PagePara para) {
        List<IncomeRecordDto> walletList = psUserInfoMapper.getBillList(para.getStatus(), para.getPage(), para.getSize(), para.getUserId());
        return new BaseResult(0, walletList);
    }

    @Override
    public BaseResult accruingAmounts(Long id) {
        JyPetrolStationOrder order=psUserInfoMapper.accruingAmounts(id);
        return new BaseResult(0,order);
    }

    @Override
    public BaseResult payQrcode(Long userId) throws Exception {
        BufferedImage image=createImage("3,"+userId);
        String url=upoos(image);
        //生成二维码存入redis 过期时间设置暂定为1分钟  过期将不可用
        redisTemplate.delete(SystemPath.APP_PAY_QRCODE_PATH +userId);
        //设置有效期5分钟
        redisTemplate.boundValueOps(SystemPath.APP_RESGTION_CODE_PATH + userId).set(url, 1, TimeUnit.MINUTES);
        return new BaseResult(0,new QrcodeDto(url));
    }

    @Override
    public BaseResult withdrawRecord(Long useId, PagePara page, WithdrawPara para) {
        List<UserWithdraw> list=uirm.selectWithdrawRecordList(page,useId,para.getStartDate(),para.getEndDate());
        return new BaseResult(0,list);
    }
}
